Javascript DOM编程艺术读书笔记6

第6章 案例研究:图片库改进版

  • 问题:结构和行为没有分离
  • 解决方法:引入许多测试和检查使JS代码可以平稳退化,将实践处理函数从标记文档分离到了一个外部的JS文件,使JS代码不再依赖于HTML文档的内容和结构。

图片库一次改进

gallery.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Image Gallery</title>
<link rel="stylesheet" type="text/css" href="styles/layout.css" media="screen">
</head>

<body>
<h1>Snapshots</h1>
<ul id="imagegallery">
<li>
<a href="images/1.jpg" title="A fireworks display"><img src="images/1.jpg" alt="fireworks"></a>
</li>
<li>
<a href="images/2.jpg" title="A cup of black coffee"><img src="images/2.jpg" alt="coffee"></a>
</li>
<li>
<a href="images/3.jpg" title="A red, red rose"><img src="images/3.jpg" alt="rose"></a>
</li>
</ul>
<img id="placeholder" src="images/placeholder.gif"/>
<p id="description">Choose an image</p>
<script src="scripts/showPic.js">
</script>
</body>

</html>

showPic.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
addLoadEvent(prepareGallery);

function addLoadEvent(func) {
//把现有的window.onload事件梳理函数的值存入变量oldonload
var oldonload = window.onload;
//如果这个处理函数上还没有绑定任何函数,就把新函数添加给她
if (typeof window.onload != 'function') {
window.onload = func;
} else {
//如果已经绑定了一些函数,就把新函数追加到现有指令的末尾
window.onload = function() {
oldonload();
func();
}
}
}

function prepareGallery() {
//1.检查点。不理解DOM方法的浏览器不执行这个函数
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
//即使html页面中删除图片库,js代码也不会出错。JS代码不应该对网页的结构有任何依赖
if (!document.getElementById("imagegallery")) return false;
//imagegallery中的所有链接
var gallery = document.getElementById("imagegallery");
var links = gallery.getElementsByTagName("a");
//遍历
for (var i = 0; i < links.length; i++) {
//定义一个匿名函数
links[i].onclick = function() {
//this指的是links[i]。如果showPic(this)返回true,就返回false,浏览器不会打开那个链接。如果showPic(this)返回false,就返回true以允许默认行为发生
return showPic(this) ? false : true;

}
}
}

function showPic(whichpic) {
//检查特定的placeholder元素是否存在
if (!document.getElementById("placeholder")) return false;
var source = whichpic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
if (placeholder.nodeName != "IMG") return false;
placeholder.setAttribute("src", source);
//如果description元素存在,将会被更新,如果不存在就会被忽略。
if (document.getElementById("description")) {
//如果title属性存在,text将被赋值为whichpic.getAttribute("title"),如果不存在就是空字符串
var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
var description = document.getElementById("description");
//description元素的第一个子元素是否是一个文本节点
if (description.firstChild.nodeType == 3) {
description.firstChild.nodeValue = text;
}
}
return true;
}

showPic的另一种方法,与上一种的true false相反

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
addLoadEvent(prepareGallery);
function addLoadEvent(func){ //多个函数绑定到onload事件处理函数上
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
}else{
window.onload = function(){
oldonload();
func();
}
}
}
function prepareGallery(){ //该方法只在页面加载完毕后才执行。
if(!document.getElementById) return false;
if(!document.getElementsByTagName) return false;
if(!document.getElementById("imagegallery")) return false; //预留后路
var gallery = document.getElementById("imagegallery"); //将html和js通过id标识进行连接,分离javascript
var links = gallery.getElementsByTagName("a");
for(var i=0;i<links.length;i++){
links[i].onclick = function(){
return showPic(this);
}
}
}
function showPic(whichpic){
if(!document.getElementById("placeholder")) return true; //如果没有该元素,返回true使a标签的默认行为发生,即href有效
var source = whichpic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src",source);
if(!document.getElementById("description")) return false; //假设没有p元素,照片照常显示,返回false后,不会执行a标签中的href
var text = whichpic.getAttribute("title");
var description = document.getElementById("description");
description.firstChild.nodeValue = text;
return false;
}

layout.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
body {
font-family: "Helvetica", "Arial", serif;
color: #333;
background-color: #ccc;
margin: 1em 10%;
}

h1 {
color: #333;
background-color: transparent;
}

a {
color: #c60;
background-color: transparent;
font-weight: bold;
text-decoration: none;
}

ul {
padding: 0;
}

li {
float: left;
padding: 1em;
list-style: none;
}

img {
display: block;
clear: both;
}

#imagegallery {
list-style: none;
}

#imagegallery li{
display: inline;
}

#imagegallery li a img {
width: 10em;
height: 10em;
border: 0;
}